﻿using System;
using System.Collections.Generic;

// 定义一个异常类，表示有坏的钞票
public class BadCashException : Exception
{
    public BadCashException(string message) : base(message) { }
}

// 定义一个枚举类型，表示账号类型
public enum AccountType
{
    Savings,
    Checking,
    Credit
}

// 定义一个接口，表示账号的基本行为
public interface IAccount
{
    string AccountNumber { get; }
    double Balance { get; }
    void Deposit(double amount);
    void Withdraw(double amount);
}

// 定义一个银行账号类
public class Account : IAccount
{
    private string accountNumber;
    private double balance;

    public Account(string accountNumber, double initialBalance)
    {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    public string AccountNumber => accountNumber;

    public double Balance => balance;

    public void Deposit(double amount)
    {
        if (amount < 0)
        {
            throw new ArgumentException("Deposit amount must be positive.");
        }
        balance += amount;
    }

    public void Withdraw(double amount)
    {
        if (amount < 0)
        {
            throw new ArgumentException("Withdrawal amount must be positive.");
        }

        if (amount > balance)
        {
            throw new InvalidOperationException("Insufficient funds.");
        }

        balance -= amount;
    }
}

// 定义一个信用账号类，继承自账号类
public class CreditAccount : Account
{
    public double CreditLimit { get; private set; }

    public CreditAccount(string accountNumber, double initialBalance, double creditLimit)
        : base(accountNumber, initialBalance)
    {
        CreditLimit = creditLimit;
    }

    public override void Withdraw(double amount)
    {
        if (amount < 0)
        {
            throw new ArgumentException("Withdrawal amount must be positive.");
        }

        if (amount > (Balance + CreditLimit))
        {
            throw new InvalidOperationException("Exceeds credit limit.");
        }

        if (amount > Balance)
        {
            double creditUsed = amount - Balance;
            CreditLimit -= creditUsed;
            base.Withdraw(Balance);
        }
        else
        {
            base.Withdraw(amount);
        }
    }
}

// 定义一个结构，表示大笔金额取款事件的参数
public struct BigMoneyArgs
{
    public IAccount Account { get; }
    public double WithdrawalAmount { get; }

    public BigMoneyArgs(IAccount account, double withdrawalAmount)
    {
        Account = account;
        WithdrawalAmount = withdrawalAmount;
    }
}

// 定义一个委托类型，用于处理大笔金额取款事件
public delegate void BigMoneyHandler(object sender, BigMoneyArgs args);

// 定义一个 ATM 类
public class ATM
{
    // 事件：大笔金额取款
    public event BigMoneyHandler BigMoneyFetched;

    // 模拟 ATM 取款操作
    public void WithdrawMoney(IAccount account, double amount)
    {
        if (amount > 10000)
        {
            // 激活大笔金额取款事件
            BigMoneyArgs args = new BigMoneyArgs(account, amount);
            BigMoneyFetched?.Invoke(this, args);
        }

        // 模拟随机坏钞率为30%
        if (new Random().NextDouble() < 0.3)
        {
            throw new BadCashException("Bad cash detected.");
        }

        account.Withdraw(amount);
    }
}

class Program
{
    static void Main()
    {
        // 创建信用账号
        CreditAccount creditAccount = new CreditAccount("12345", 1000, 5000);

        // 创建 ATM
        ATM atm = new ATM();

        // 注册大笔金额取款事件处理程序
        atm.BigMoneyFetched += (sender, args) =>
        {
            Console.WriteLine($"Warning: Large withdrawal of {args.WithdrawalAmount:C} from account {args.Account.AccountNumber}");
        };

        try
        {
            // 模拟取款操作
            atm.WithdrawMoney(creditAccount, 15000);
        }
        catch (BadCashException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }

        Console.WriteLine($"Account balance: {creditAccount.Balance:C}");
        Console.WriteLine($"Credit limit remaining: {creditAccount.CreditLimit:C}");
    }
}
